export default class ArrayStack<T = any> {
	private _list: T[] = [];

	public get list(): T[] {
		return this._list;
	}
	public set list(value: T[]) {
		this._list = value;
	}

	public get size(): number {
		return this._list.length;
	}

	public get empty(): boolean {
		return this.size === 0;
	}

	public get top(): T | undefined {
		const { _list } = this;
		return _list[0];
	}

	public get topCheck(): T {
		if (this.empty) { throw new Error("栈为空"); }
		return this._list[0];
	}
	public set topCheck(value: T) {
		if (this.empty) { throw new Error("栈为空"); }
		this._list[0] = value;
	}

	public constructor(list?: T[]) {
		if (list !== undefined) {
			this._list = list;
		}
	}

	public push(value: T): void {
		this._list.unshift(value);
	}

	public pop(): T {
		if (this._list.length === 0) {
			throw new Error("突破栈底");
		}
		return this._list.shift() as T;
	}

	public has(value: T): boolean {
		return this._list.includes(value);
	}

	public copy(callbackfn?: (value: T, index: number, array: T[]) => T): ArrayStack<T> {
		const { _list } = this;
		const ret = new ArrayStack<T>();
		ret._list = callbackfn === undefined ? _list.map(info => info) : _list.map(callbackfn);
		return ret;
	}
}
